home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / DELPHI32 / BUTTONS / RBUTTON / RBUTTON.PAS < prev    next >
Pascal/Delphi Source File  |  1996-11-05  |  10KB  |  305 lines

  1. {-------------------------------------------------------------
  2. -RButton: Visible Component used to display round buttons    -
  3. -         instead of square.  Works identical to the standard-
  4. -         TSpeedButton component.                            -
  5. --------------------------------------------------------------
  6. - !INSTALLATION!:  In Delphi, go to Options|Install Component-
  7. - and Add BPReg.pas.  This will add both components.         -
  8. --------------------------------------------------------------
  9. -Programmed by Brendan Rempel, October 1996                  -
  10. -Copyright 1996; All Rights Reserved                         -
  11. -Send any comments/change requests/etc. to:                  -
  12. -   rempelb@mail.pr-unlimited.com                            -
  13. -                                                            -
  14. -This component is hereby given to the public domain.  I do  -
  15. -claim copyright of this code and I hereby prohibit the sale -
  16. -of the source or compiled code to anyone for any amount.    -
  17. -------------------------------------------------------------}
  18. unit Rbutton;
  19.  
  20. interface
  21.  
  22. uses
  23.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  24.   Forms, Dialogs;
  25.  
  26. const
  27.   DefaultWidth = 40;
  28.   DefaultHeight = 40;
  29.  
  30. type
  31.   TNumGlyphs = 1..4;
  32.   TRButtonType = (rtRegular,rtInset);
  33.  
  34. type
  35.   TRoundButton = class(TGraphicControl)
  36.   private
  37.     FGlyph:            TBitmap;
  38.     FNumGlyphs:        TNumGlyphs;
  39.     FDown:             boolean;
  40.     FTransparentColor: TColor;
  41.     FMouseDown:        boolean;
  42.     FMouseInside:      boolean;
  43.     FOnClick:          TNotifyEvent;
  44.     FRButtonType:      TRButtonType;
  45.     FOnMouseEnter:     TNotifyEvent;
  46.     FOnMouseExit:      TNotifyEvent;
  47.  
  48.   protected
  49.     procedure Paint;  override;
  50.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  51.        override;
  52.     procedure MouseMove(Shift: TShiftState; X, Y: Integer);
  53.        override;
  54.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  55.        override;
  56.  
  57.     function  IsInsideButton(X,Y: Integer): boolean;
  58.  
  59.     procedure SetGlyph(newGlyph: TBitmap);
  60.     procedure SetNumGlyphs(newNumGlyphs: TNumGlyphs);
  61.     procedure SetTransparentColor(newTransparentColor: TColor);
  62.     procedure SetRButtonType(newRButtonType: TRButtonType);
  63.  
  64.     procedure PaintButton;
  65.  
  66.   public
  67.     constructor Create(AOwner: TComponent); override;
  68.     destructor Destroy; override;
  69.  
  70.   published
  71.     property ButtonType: TRButtonType read FRButtonType write SetRButtonType;
  72.     property Enabled;
  73.     property Glyph: TBitmap read FGlyph write SetGlyph;
  74.     property NumGlyphs: TNumGlyphs read FNumGlyphs write SetNumGlyphs default 1;
  75.     property ParentShowHint;
  76.     property ShowHint;
  77.     property TransparentColor: TColor read FTransparentColor write SetTransparentColor;
  78.     property Visible;
  79.     property OnClick:   TNotifyEvent read FOnClick write FOnClick;
  80.     property OnMouseDown;
  81.     property OnMouseMove;
  82.     property OnMouseUp;
  83.  
  84.     property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
  85.     property OnMouseExit:  TNotifyEvent read FOnMouseExit  write FOnMouseExit;
  86.   end;
  87.  
  88. implementation
  89.  
  90. constructor TRoundButton.Create(AOwner: TComponent);
  91. begin
  92.    inherited Create(AOwner);
  93.  
  94.    FGlyph:= TBitmap.Create;
  95.    FNumGlyphs:= 1;
  96.    FDown:=  False;
  97.    FMouseInside:= False;
  98.    Width:=  DefaultWidth;
  99.    Height:= DefaultHeight;
  100.  
  101.    FMouseDown:= False;
  102. end;
  103.  
  104. destructor  TRoundButton.Destroy;
  105. begin
  106.    FGlyph.Free;
  107.    inherited Destroy;
  108. end;
  109.  
  110. procedure TRoundButton.SetGlyph(newGlyph: TBitmap);
  111. begin
  112.    if(Assigned(FGlyph)) then
  113.    begin
  114.       FGlyph.Assign(newGlyph);
  115.  
  116.       if (csDesigning in ComponentState) then
  117.       begin
  118.          { bitmap 1: main, 2: disabled, 3: down;
  119.            must have dimensions of (height * NoBitmaps) = width }
  120.          if (newGlyph.width mod newGlyph.height = 0) then
  121.             FNumGlyphs:= newGlyph.width div newGlyph.height
  122.          else
  123.             FNumGlyphs:= 1;
  124.       end;
  125.  
  126.       Invalidate;
  127.    end;
  128. end;
  129.  
  130. procedure TRoundButton.SetNumGlyphs(newNumGlyphs: TNumGlyphs);
  131. begin
  132.    FNumGlyphs:= newNumGlyphs;
  133.    Invalidate;
  134. end;
  135.  
  136. procedure TRoundButton.SetRButtonType(newRButtonType: TRButtonType);
  137. begin
  138.    FRButtonType:= newRButtonType;
  139.    Invalidate;
  140. end;
  141.  
  142. procedure TRoundButton.SetTransparentColor(newTransparentColor: TColor);
  143. begin
  144.    FTransparentColor:= newTransparentColor;
  145.    Invalidate;
  146. end;
  147.  
  148. function TRoundButton.IsInsideButton(X,Y: Integer): boolean;
  149. var
  150.    Hypotonuse: integer;
  151. begin
  152.    X:= Abs((Width shr 1) - X);  { calculate the (X,Y) distance }
  153.    Y:= Abs((Height shr 1) - Y);
  154.  
  155.    Hypotonuse:= Round(Sqrt(Abs((X * X) + (Y * Y))));
  156.                                 { calculate hypotenuse (distance from center) }
  157.  
  158.    Result:= (Hypotonuse <= (Width shr 1)-1);
  159.                                 { return true if Hypotonuse less than half of width }
  160. end;
  161.  
  162. procedure TRoundButton.Paint;
  163. begin
  164.    with Canvas do
  165.    begin
  166.       brush.color:= clBtnFace;
  167.  
  168.       case FRButtonType of
  169.          rtRegular:
  170.          begin
  171.             pen.color:= clBlack;
  172.             Ellipse(0,0,width-1,height-1); { fill inner button, black edge }
  173.          end;
  174.          rtInset:
  175.          begin
  176.             pen.color:= clBtnFace;
  177.             Ellipse(1,1,width-2,height-2); { fill inner button }
  178.  
  179.             pen.color:= clBtnShadow;       { shadowed edge }
  180.             Arc(0,0,width-1,height-1,width div 5 * 4,height div 5,width div 5,height div 5 * 4);
  181.             pen.color:= clBtnHighlight;    { highlighted edge }
  182.             Arc(0,0,width-1,height-1,width div 5,height div 5 * 4,width div 5 * 4,height div 5);
  183.          end;
  184.       end;
  185.    end;
  186.  
  187.    PaintButton;                            { repaint rest }
  188. end;
  189.  
  190. procedure TRoundButton.PaintButton;
  191. var
  192.    Dest,Source: TRect;
  193.    outWidth,outHeight: integer;
  194. begin
  195.    if Assigned(FGlyph) then                { if has a bitmap }
  196.    begin
  197.       with Source do
  198.       begin                                { setup bounding rectangle }
  199.          Left:= 0; Top:= 0; Right:= FGlyph.Width; Bottom:= FGlyph.Height;
  200.  
  201.          if FNumGlyphs > 0 then
  202.             Right:= Right div FNumGlyphs;
  203.       end;
  204.    end;
  205.  
  206.    with Canvas do
  207.    begin                                   { draw top left edge }
  208.       if FDown then  pen.color:= clBtnShadow else pen.color:= clBtnHighlight;
  209.       Arc(1,1,width-2,height-2,width div 5 * 4,height div 5,width div 5,height div 5 * 4);
  210.                                            { draw bottom right edge }
  211.       if Not FDown then  pen.color:= clBtnShadow else pen.color:= clBtnHighlight;
  212.       Arc(1,1,width-2,height-2,width div 5,height div 5 * 4,width div 5 * 4,height div 5);
  213.  
  214. {---place glyph---------------------------------------}
  215.       if Assigned(FGlyph) and (FNumGlyphs > 0) then
  216.       begin
  217.          if(Not Enabled and (FNumGlyphs > 1)) then
  218.          begin                             { draw disabled button }
  219.             Source.Left:=  FGlyph.width div FNumGlyphs;
  220.             Source.Right:= Source.Left shl 1;
  221.          end;
  222.                                            { setup output image retangle }
  223.          outWidth:=  Source.Right-Source.Left;
  224.          outHeight:= Source.Bottom-Source.Top;
  225.                                            { find center }
  226.          Dest.Left:=  ((Width  - outWidth)  shr 1);
  227.          Dest.Right:= ((Width  - outWidth)  shr 1)+outWidth;
  228.          Dest.Top:=   ((Height - outHeight) shr 1);
  229.          Dest.Bottom:=((Height - outHeight) shr 1)+outHeight;
  230.  
  231.          Pen.Color:= clBtnFace;
  232.  
  233.          if FDown then
  234.          begin                        { shift image position down and right 1 }
  235.             Inc(Dest.Left); Inc(Dest.Right); Inc(Dest.Top); Inc(Dest.Bottom);
  236.                                            { clear ghost }
  237.             MoveTo(Dest.Left-1,Dest.Bottom);
  238.             LineTo(Dest.Left-1,Dest.Top-1);
  239.             LineTo(Dest.Right,Dest.Top-1);
  240.          end
  241.          else
  242.          begin                             { clear ghost }
  243.             MoveTo(Dest.Right,Dest.Top);
  244.             LineTo(Dest.Right,Dest.Bottom);
  245.             LineTo(Dest.Left,Dest.Bottom);
  246.          end;
  247.  
  248.          if(FDown and (FNumGlyphs > 2)) then { show pushed image if available }
  249.          begin
  250.             Source.Left:= FGlyph.width div FNumGlyphs * 2;
  251.             Source.Right:=FGlyph.width div FNumGlyphs * 3;
  252.          end;
  253.          Brush.Color:= clBtnFace;          { paint transparent image }
  254.          BrushCopy(Dest,FGlyph,Source,FTransparentColor);
  255.       end;
  256.    end;
  257. end;
  258.  
  259. procedure TRoundButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  260. begin
  261.    if (Enabled and IsInsideButton(X,Y)) then
  262.    begin
  263.       FDown:= True;                        { push button and repaint }
  264.       PaintButton;
  265.    end;
  266.    FMouseDown:= True;
  267. end;
  268.  
  269. procedure TRoundButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  270. begin
  271.    if (Enabled and IsInsideButton(X,Y)) then
  272.    begin
  273.       FDown:= False;                       { release button and repaint }
  274.       PaintButton;
  275.       if Assigned(FOnClick) then           { issue event to application }
  276.          FOnClick(Self);
  277.    end;
  278.    FMouseDown:= False;
  279. end;
  280.  
  281. procedure TRoundButton.MouseMove(Shift: TShiftState; X, Y: Integer);
  282. begin
  283.    if FMouseDown then
  284.    begin
  285.       if Not IsInsideButton(X,Y) then
  286.       begin
  287.          if FDown then                     { mouse has slid off, so release }
  288.          begin
  289.             FDown:= False;
  290.             PaintButton;
  291.          end;
  292.       end
  293.       else
  294.       begin
  295.          if Not FDown then                 { mouse has slid back on, so push }
  296.          begin
  297.             FDown:= True;
  298.             PaintButton;
  299.          end;
  300.       end;
  301.    end;
  302. end;
  303.  
  304. end.
  305.